package actor

import (
	"errors"
)

// ErrActorNameExists 当spawn的actor名字已存在时候返回此错误
var ErrActorNameExists = errors.New("spawn: name exists")

func Spawn(props *Props) *PID {
	pid, _ := spawn(gProcessManager.NextName(), props, nil)
	return pid
}

func SpawnPrefix(props *Props, prefix string) (*PID, error) {
	return spawn(prefix+gProcessManager.NextName(), props, nil)
}

func SpawnNamed(props *Props, name string) (*PID, error) {
	return spawn(name, props, nil)
}

func spawn(name string, props *Props, parent *PID) (*PID, error) {
	lp := newLocalProcess(props.mailboxSize, props.mailboxScheduleCount)

	pid, absent := gProcessManager.Add(lp, name)
	if !absent {
		return pid, ErrActorNameExists
	}
	var ref IProcess = lp
	pid.process = &ref

	a := props.actorProducer()
	ctx := newLocalContext(a, pid, parent, props.supervisorFunc)

	lp.ctx = ctx
	lp.Start()

	return pid, nil
}
